﻿/*--------------------------------------------------------------------
 * Author : Tharinduni Udugamasuriya
 * Date : 29 October 2014
 * TransactionToolBar : TransactionToolBar User Control's Code Behind
 --------------------------------------------------------------------*/

using CrystalDecisions.CrystalReports.Engine;
using DSPL.Common.Classes;
using DSPL.Common.ViewModel;
using DSPL.Contracts;
using DSPL.Contracts.Common;
using DSPL.Contracts.Interfaces;
using DSPL.Reports.Classes;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Linq;


namespace DSPL.Common
{
    /// <summary>
    /// Interaction logic for TransactionToolBar.xaml
    /// </summary>
    public partial class TransactionToolBar : UserControl
    {
        public TransactionToolBar()
        {
            InitializeComponent();
            if (DesignerProperties.GetIsInDesignMode(this))
                return;

            ResolveDependancies();
        }

        public void ResolveDependancies()
        {
            IUnityContainer container = GlobalVariables.GlobalUnityContainer;
            if (container != null)
           {
                ReadService = container.Resolve<IReadService>();
                WriteService = container.Resolve<IWriteService>();
                ColumnWithValue = container.Resolve<IColumnWithValue>();
                CommonValidations = container.Resolve<ICommonValidations>();
                MessageService = container.Resolve<IMessageService>();
            }
        }

        #region Declaring User Control Internal/Private/Protected Variables

        private string firstFocusElement;
        private int currentIndex;
        DataRow NewDataRow;
        DataRow OldDataRow;
        private string uniqueKey;
        private bool isSaveEnable;
        private bool isViewEnable;
        private bool isNavigationEnable;
        private bool isFirst;
        private bool isLast;
        object primaryKey;
        private string referenceNo;
        private string primaryKeyField = string.Empty;
        private string referenceNoField = string.Empty;
        private string reportName = string.Empty;
        private DataTable dtDummyChild = null;
        private DataTable dtChildTxn = null;
        private string parentTable = string.Empty;
        private string childTable = string.Empty;
        private HelpNames gridDataHelp;
        private string genRef = string.Empty;

        #endregion

        #region Declaring Dependency Properties

        #region Visibility of Buttons

        public static readonly DependencyProperty NewVisibilityProperty = DependencyProperty.Register("NewVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty EditVisibilityProperty = DependencyProperty.Register("EditVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty DeleteVisibilityProperty = DependencyProperty.Register("DeleteVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty UndoVisibilityProperty = DependencyProperty.Register("UndoVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty FirstVisibilityProperty = DependencyProperty.Register("FirstVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty PreviousVisibilityProperty = DependencyProperty.Register("PreviousVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty NextVisibilityProperty = DependencyProperty.Register("NextVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty LastVisibilityProperty = DependencyProperty.Register("LastVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty PrintVisibilityProperty = DependencyProperty.Register("PrintVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty ListVisibilityProperty = DependencyProperty.Register("ListVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty SearchVisibilityProperty = DependencyProperty.Register("SearchVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty FilterVisibilityProperty = DependencyProperty.Register("FilterVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty SortVisibilityProperty = DependencyProperty.Register("SortVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty SaveVisibilityProperty = DependencyProperty.Register("SaveVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty CloseVisibilityProperty = DependencyProperty.Register("CloseVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty ApproveVisibilityProperty = DependencyProperty.Register("ApproveVisibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty Button1VisibilityProperty = DependencyProperty.Register("Button1Visibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty Button2VisibilityProperty = DependencyProperty.Register("Button2Visibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty Button3VisibilityProperty = DependencyProperty.Register("Button3Visibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty Button4VisibilityProperty = DependencyProperty.Register("Button4Visibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty Button5VisibilityProperty = DependencyProperty.Register("Button5Visibility", typeof(Visibility), typeof(TransactionToolBar), new PropertyMetadata(Visibility.Visible));

        #endregion

        public static readonly DependencyProperty ChildTableNameProperty = DependencyProperty.Register("ChildTableName", typeof(string), typeof(TransactionToolBar), new PropertyMetadata("abc"), new ValidateValueCallback(TableNameValidateCallBack));
        public static readonly DependencyProperty ParentTableNameProperty = DependencyProperty.Register("ParentTableName", typeof(string), typeof(TransactionToolBar), new PropertyMetadata("abc"), new ValidateValueCallback(TableNameValidateCallBack));
        public static readonly DependencyProperty LogChildTableProperty = DependencyProperty.Register("LogChildTable", typeof(string), typeof(TransactionToolBar), new PropertyMetadata("abc"), new ValidateValueCallback(TableNameValidateCallBack));
        public static readonly DependencyProperty LogParentTableProperty = DependencyProperty.Register("LogParentTable", typeof(string), typeof(TransactionToolBar), new PropertyMetadata("abc"), new ValidateValueCallback(TableNameValidateCallBack));
        public static readonly DependencyProperty TempChildTableProperty = DependencyProperty.Register("TempChildTable", typeof(string), typeof(TransactionToolBar), new PropertyMetadata("abc"));
        public static readonly DependencyProperty TempParentTableProperty = DependencyProperty.Register("TempParentTable", typeof(string), typeof(TransactionToolBar), new PropertyMetadata("abc"));
        public static readonly DependencyProperty CurrentRowProperty = DependencyProperty.Register("CurrentRow", typeof(DataRow), typeof(TransactionToolBar), new PropertyMetadata(null, OnCurrentRowChanged));
        public static readonly DependencyProperty SqlTranProperty = DependencyProperty.Register("SqlTran", typeof(SqlTransaction), typeof(TransactionToolBar), new PropertyMetadata(null));
        public static readonly DependencyProperty IsValidProperty = DependencyProperty.Register("IsValid", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty FormModeProperty = DependencyProperty.Register("FormMode", typeof(Modes), typeof(TransactionToolBar), new PropertyMetadata(Modes.Undo, FormModeChangedCallBack));
        public static readonly DependencyProperty IgnoreTableListProperty = DependencyProperty.Register("IgnoreTableList", typeof(string), typeof(TransactionToolBar), new PropertyMetadata(""));
        public static readonly DependencyProperty ReportFolderProperty = DependencyProperty.Register("ReportFolder", typeof(string), typeof(TransactionToolBar), new PropertyMetadata(""));
        public static readonly DependencyProperty DtParentTxnDataProperty = DependencyProperty.Register("DtParentTxnData", typeof(DataTable), typeof(TransactionToolBar), new PropertyMetadata(null));
        public static readonly DependencyProperty DtChildTxnDataProperty = DependencyProperty.Register("DtChildTxnData", typeof(DataTable), typeof(TransactionToolBar), new PropertyMetadata(null));
        public static readonly DependencyProperty AdditionalReportParametersProperty = DependencyProperty.Register("AdditionalReportParameters", typeof(List<IReportParameters>), typeof(TransactionToolBar), new PropertyMetadata(null));
        public static readonly DependencyProperty TransactionDateProperty = DependencyProperty.Register("TransactionDate", typeof(DateTime), typeof(TransactionToolBar), new PropertyMetadata(DateTime.Now));
        public static readonly DependencyProperty BranchPrefixProperty = DependencyProperty.Register("BranchPrefix", typeof(string), typeof(TransactionToolBar), new PropertyMetadata(string.Empty));
        public static readonly DependencyProperty RefGenCodeProperty = DependencyProperty.Register("RefGenCode", typeof(string), typeof(TransactionToolBar), new PropertyMetadata(string.Empty));
        public static readonly DependencyProperty TempRefGenCodeProperty = DependencyProperty.Register("TempRefGenCode", typeof(string), typeof(TransactionToolBar), new PropertyMetadata(string.Empty));
        public static readonly DependencyProperty ChildGridHelpNameProperty = DependencyProperty.Register("ChildGridHelpName", typeof(HelpNames), typeof(TransactionToolBar), new PropertyMetadata(HelpNames.Default));
        public static readonly DependencyProperty ChildGridTempHelpNameProperty = DependencyProperty.Register("ChildGridTempHelpName", typeof(HelpNames), typeof(TransactionToolBar), new PropertyMetadata(HelpNames.Default));
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(TransactionToolBar), new PropertyMetadata(string.Empty));
        
        #region Methods Execute Type

        public static readonly DependencyProperty IsDataValidateExecuteProperty = DependencyProperty.Register("IsDataValidateExecute", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsDataUpdValidateExecuteProperty = DependencyProperty.Register("IsDatUpdaValidateExecute", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsDataDelValidateExecuteProperty = DependencyProperty.Register("IsDataDelValidateExecute", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsDataSaveProperty = DependencyProperty.Register("IsDataSave", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsDataUpdateProperty = DependencyProperty.Register("IsDataUpdate", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsDataDeleteProperty = DependencyProperty.Register("IsDataDelete", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsApprovalProperty = DependencyProperty.Register("IsApproval", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(false));
        public static readonly DependencyProperty IsResetDefaultExecuteProperty = DependencyProperty.Register("IsResetDefaultExecute", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));
        public static readonly DependencyProperty IsDataGridLoadExecuteProperty = DependencyProperty.Register("IsDataGridLoadExecute", typeof(bool), typeof(TransactionToolBar), new PropertyMetadata(true));

        #endregion

        #endregion

        #region Declaring Properties

        public IReadService ReadService { get; set; }
        public IWriteService WriteService { get; set; }
        public IColumnWithValue ColumnWithValue { get; set; }
        public ICommonValidations CommonValidations { get; set; }
        public IMessageService MessageService { get; set; }

        #region Visibility of Buttons

        public Visibility NewVisibility
        {
            get { return (Visibility)GetValue(NewVisibilityProperty); }
            set { SetValue(NewVisibilityProperty, value); }
        }

        public Visibility EditVisibility
        {
            get { return (Visibility)GetValue(EditVisibilityProperty); }
            set { SetValue(EditVisibilityProperty, value); }
        }

        public Visibility DeleteVisibility
        {
            get { return (Visibility)GetValue(DeleteVisibilityProperty); }
            set { SetValue(DeleteVisibilityProperty, value); }
        }

        public Visibility UndoVisibility
        {
            get { return (Visibility)GetValue(UndoVisibilityProperty); }
            set { SetValue(UndoVisibilityProperty, value); }
        }

        public Visibility FirstVisibility
        {
            get { return (Visibility)GetValue(FirstVisibilityProperty); }
            set { SetValue(FirstVisibilityProperty, value); }
        }

        public Visibility PreviousVisibility
        {
            get { return (Visibility)GetValue(PreviousVisibilityProperty); }
            set { SetValue(PreviousVisibilityProperty, value); }
        }

        public Visibility NextVisibility
        {
            get { return (Visibility)GetValue(NextVisibilityProperty); }
            set { SetValue(NextVisibilityProperty, value); }
        }

        public Visibility LastVisibility
        {
            get { return (Visibility)GetValue(LastVisibilityProperty); }
            set { SetValue(LastVisibilityProperty, value); }
        }

        public Visibility PrintVisibility
        {
            get { return (Visibility)GetValue(PrintVisibilityProperty); }
            set { SetValue(PrintVisibilityProperty, value); }
        }

        public Visibility ListVisibility
        {
            get { return (Visibility)GetValue(ListVisibilityProperty); }
            set { SetValue(ListVisibilityProperty, value); }
        }

        public Visibility SearchVisibility
        {
            get { return (Visibility)GetValue(SearchVisibilityProperty); }
            set { SetValue(SearchVisibilityProperty, value); }
        }

        public Visibility FilterVisibility
        {
            get { return (Visibility)GetValue(FilterVisibilityProperty); }
            set { SetValue(FilterVisibilityProperty, value); }
        }

        public Visibility SortVisibility
        {
            get { return (Visibility)GetValue(SortVisibilityProperty); }
            set { SetValue(SortVisibilityProperty, value); }
        }

        public Visibility SaveVisibility
        {
            get { return (Visibility)GetValue(SaveVisibilityProperty); }
            set { SetValue(SaveVisibilityProperty, value); }
        }

        public Visibility CloseVisibility
        {
            get { return (Visibility)GetValue(CloseVisibilityProperty); }
            set { SetValue(CloseVisibilityProperty, value); }
        }

        public Visibility ApproveVisibility
        {
            get { return (Visibility)GetValue(ApproveVisibilityProperty); }
            set { SetValue(ApproveVisibilityProperty, value); }
        }

        public Visibility Button1Visibility
        {
            get { return (Visibility)GetValue(Button1VisibilityProperty); }
            set { SetValue(Button1VisibilityProperty, value); }
        }

        public Visibility Button2Visibility
        {
            get { return (Visibility)GetValue(Button2VisibilityProperty); }
            set { SetValue(Button2VisibilityProperty, value); }
        }

        public Visibility Button3Visibility
        {
            get { return (Visibility)GetValue(Button3VisibilityProperty); }
            set { SetValue(Button3VisibilityProperty, value); }
        }

        public Visibility Button4Visibility
        {
            get { return (Visibility)GetValue(Button4VisibilityProperty); }
            set { SetValue(Button4VisibilityProperty, value); }
        }

        public Visibility Button5Visibility
        {
            get { return (Visibility)GetValue(Button5VisibilityProperty); }
            set { SetValue(Button5VisibilityProperty, value); }
        }

        #endregion

        #region General Properties

        public DataTable DtParentLogTableData { get; private set; }

        public DataTable DtChildLogTableData { get; private set; }

        public DataTable DtOldChildTxnData { get; private set; }

        public List<IReportParameters> AdditionalReportParameters
        {
            get { return (List<IReportParameters>)GetValue(AdditionalReportParametersProperty); }
            set { SetValue(AdditionalReportParametersProperty, value); }
        }

        public string ParentTableName
        {
            get { return (string)GetValue(ParentTableNameProperty); }
            set { SetValue(ParentTableNameProperty, value); }
        }

        public string ChildTableName
        {
            get { return (string)GetValue(ChildTableNameProperty); }
            set { SetValue(ChildTableNameProperty, value); }
        }

        public string TempParentTable
        {
            get { return (string)GetValue(TempParentTableProperty); }
            set { SetValue(TempParentTableProperty, value); }
        }

        public string TempChildTable
        {
            get { return (string)GetValue(TempChildTableProperty); }
            set { SetValue(TempChildTableProperty, value); }
        }

        public string LogParentTable
        {
            get { return (string)GetValue(LogParentTableProperty); }
            set { SetValue(LogParentTableProperty, value); }
        }
        
        public string LogChildTable
        {
            get { return (string)GetValue(LogChildTableProperty); }
            set { SetValue(LogChildTableProperty, value); }
        }

        public Modes FormMode
        {
            get { return (Modes)GetValue(FormModeProperty); }
            set
            {
                SetValue(FormModeProperty, value);
                EnableDisableButtons(FormMode);
            }
        }

        public string FirstFocusElement
        {
            get { return firstFocusElement; }
            set { firstFocusElement = value; }
        }

        public DataRow CurrentRow
        {
            get { return (DataRow)GetValue(CurrentRowProperty); }
            set { SetValue(CurrentRowProperty, value); }
        }

        public int CurrentIndex
        {
            get { return currentIndex; }
            set
            {
                currentIndex = value;
            }
        }

        public string UniqueKey
        {
            get { return uniqueKey; }
            set
            {
                uniqueKey = value;
            }
        }

        public string PrimaryKeyField
        {
            get { return primaryKeyField; }
            set
            {

                if (value == null)
                {
                    primaryKeyField = "PK";
                }
                else
                {
                    primaryKeyField = value;
                }
            }
        }

        public string ReferenceNoField
        {
            get { return referenceNoField; }
            set
            {
                if (value == null)
                {
                    referenceNoField = "RefNo";
                }
                else
                {
                    referenceNoField = value;
                }
            }
        }
        
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
        
        public string ReportFolder
        {
            get { return (string)GetValue(ReportFolderProperty); }
            set { SetValue(ReportFolderProperty, value); }
        }

        public string ReportName
        {
            get { return reportName; }
            set { reportName = value; }
        }

        public bool IsValid
        {
            get { return (bool)GetValue(IsValidProperty); }
            set { SetValue(IsValidProperty, value); }
        }

        public SqlTransaction SqlTran
        {
            get { return (SqlTransaction)GetValue(SqlTranProperty); }
            set { SetValue(SqlTranProperty, value); }
        }

        public string IgnoreTableList
        {
            get { return (string)GetValue(IgnoreTableListProperty); }
            set { SetValue(IgnoreTableListProperty, value); }
        }

        public DataTable DtChildTxnData
        {
            get { return (DataTable)GetValue(DtChildTxnDataProperty); }
            set { SetValue(DtChildTxnDataProperty, value); }
        }
       
        public DataTable DtParentTxnData
        {
            get { return (DataTable)GetValue(DtParentTxnDataProperty); }
            set { SetValue(DtParentTxnDataProperty, value); }
        }

        public string RefGenCode
        {
            get { return (string)GetValue(RefGenCodeProperty); }
            set { SetValue(RefGenCodeProperty, value); }
        }

        public string TempRefGenCode
        {
            get { return (string)GetValue(TempRefGenCodeProperty); }
            set { SetValue(TempRefGenCodeProperty, value); }
        }

        public string BranchPrefix
        {
            get { return (string)GetValue(BranchPrefixProperty); }
            set { SetValue(BranchPrefixProperty, value); }
        }

        public DateTime TransactionDate
        {
            get { return (DateTime)GetValue(TransactionDateProperty); }
            set { SetValue(TransactionDateProperty, value); }
        }

        public HelpNames ChildGridHelpName
        {
            get { return (HelpNames)GetValue(ChildGridHelpNameProperty); }
            set { SetValue(ChildGridHelpNameProperty, value); }
        }

        public HelpNames ChildGridTempHelpName
        {
            get { return (HelpNames)GetValue(ChildGridTempHelpNameProperty); }
            set { SetValue(ChildGridTempHelpNameProperty, value); }
        }

        
        
        #endregion

        #region Methods Execute Type

        public bool IsDataValidateExecute
        {
            get { return (bool)GetValue(IsDataValidateExecuteProperty); }
            set { SetValue(IsDataValidateExecuteProperty, value); }
        }

        public bool IsDataUpdValidateExecute
        {
            get { return (bool)GetValue(IsDataUpdValidateExecuteProperty); }
            set { SetValue(IsDataUpdValidateExecuteProperty, value); }
        }

        public bool IsDataDelValidateExecute
        {
            get { return (bool)GetValue(IsDataDelValidateExecuteProperty); }
            set { SetValue(IsDataDelValidateExecuteProperty, value); }
        }

        public bool IsDataSave
        {
            get { return (bool)GetValue(IsDataSaveProperty); }
            set { SetValue(IsDataSaveProperty, value); }
        }

        public bool IsDataUpdate
        {
            get { return (bool)GetValue(IsDataUpdateProperty); }
            set { SetValue(IsDataUpdateProperty, value); }
        }

        public bool IsDataDelete
        {
            get { return (bool)GetValue(IsDataDeleteProperty); }
            set { SetValue(IsDataDeleteProperty, value); }
        }

        public bool IsApproval
        {
            get { return (bool)GetValue(IsApprovalProperty); }
            set { SetValue(IsApprovalProperty, value); }
        }

        public bool IsResetDefaultExecute
        {
            get { return (bool)GetValue(IsResetDefaultExecuteProperty); }
            set { SetValue(IsResetDefaultExecuteProperty, value); }
        }

        public bool IsDataGridLoadExecute
        {
            get { return (bool)GetValue(IsDataGridLoadExecuteProperty); }
            set { SetValue(IsDataGridLoadExecuteProperty, value); }
        }        
        
        #endregion

        #endregion

        #region Exposable Event Handlers

        public event EventHandler<EventArgs> PreDataValidation;                 //use to data validate before internal method execution, when data saving
        public event EventHandler<EventArgs> PostDataValidation;                //use to data validate after internal method execution, when data saving
        public event EventHandler<EventArgs> PreDataDelValidation;              //use to data validate before internal method execution, when data delete record
        public event EventHandler<EventArgs> PostDataDelValidation;             //use to data validate after internal method execution, when data delete record
        public event EventHandler<EventArgs> PreDataInsert;                     //use to data saving processes before internal method execution, when data inserting
        public event EventHandler<EventArgs> PostDataInsert;                    //use to data saving processes after internal method execution, when data inserting
        public event EventHandler<EventArgs> PreDataUpdate;                     //use to data saving processes before internal method execution, when data updating
        public event EventHandler<EventArgs> PostDataUpdate;                    //use to data saving processes after internal method execution, when data updating
        public event EventHandler<EventArgs> PreDataDelete;                     //use to data deletion processes before internal method execution, when data deleting
        public event EventHandler<EventArgs> PostDataDelete;                    //use to data deletion processes after internal method execution, when data deleting
        public event EventHandler<EventArgs> RefreshExternalDataObjects;        //use to external data population 
        public event EventHandler<EventArgs> PostDataSaveProcess;               //use to events which used after save process 
        public event EventHandler<EventArgs> PreResetDefault;                   //use to reset form data before internal method execution
        public event EventHandler<EventArgs> PostResetDefault;                  //use to reset form data after internal method execution
        public event EventHandler<EventArgs> AddAddtionalReportParameters;      //use to adding addional report parameters to report
        public event EventHandler<EventArgs> PreDataGridLoad;                     //use to data deletion processes before internal method execution, when data deleting
        public event EventHandler<EventArgs> PostDataGridLoad;                    //use to data deletion processes after internal method execution, when data deleting
        
        #region Exposable Events for Additionl Buttons

        public event EventHandler<EventArgs> ExecuteButton1Event;
        public event EventHandler<EventArgs> ExecuteButton2Event;
        public event EventHandler<EventArgs> ExecuteButton3Event;
        public event EventHandler<EventArgs> ExecuteButton4Event;
        public event EventHandler<EventArgs> ExecuteButton5Event;

        #endregion

        #endregion

        #region Property Changed Callback Methods

        private static bool TableNameValidateCallBack(object _tableName)
        {
            return !_tableName.Equals("");
        }

        private static void FormModeChangedCallBack(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            TransactionToolBar tansactionToolBar = depObj as TransactionToolBar;

            if (tansactionToolBar != null)
                tansactionToolBar.EnableDisableButtons((Modes)e.NewValue);
        }

        private static void OnCurrentRowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TransactionToolBar transactionToolBar = d as TransactionToolBar;

            if (transactionToolBar != null)
            {
                DataRow dataRow = e.NewValue as DataRow;

                if (dataRow != null)
                {
                    transactionToolBar.primaryKey = dataRow[transactionToolBar.PrimaryKeyField];                
                    transactionToolBar.LoadGridData();
                    transactionToolBar.CheckFirstLast();
                }

                if (transactionToolBar.RefreshExternalDataObjects != null)
                    transactionToolBar.RefreshExternalDataObjects(transactionToolBar, new EventArgs());

            }
        }

        #endregion 

        #region User Control Commands

        #region AddNew Button

        private void ExecuteAddNew(object sender, RoutedEventArgs e)
        {
            FormMode = Modes.New;
            if (ApproveVisibility == Visibility.Visible)
            {
                parentTable = TempParentTable;
                childTable = TempChildTable;
                genRef = TempRefGenCode;
                gridDataHelp = ChildGridTempHelpName;
            }
            else
            {
                parentTable = ParentTableName;
                childTable = ChildTableName;
                genRef = RefGenCode;
                gridDataHelp = ChildGridHelpName;
            }

            IsValid = false;
            NewDataRow = DtParentTxnData.NewRow();
            CurrentRow = NewDataRow;
            SetFirstFocusElement();
        }       

        #endregion

        #region Edit Button

        private void ExecuteEdit(object sender, RoutedEventArgs e)
        {
            FormMode = Modes.Edit;
            if (ApproveVisibility == Visibility.Visible)
            {
                parentTable = TempParentTable;
                childTable = TempChildTable;
                genRef = TempRefGenCode;
                gridDataHelp = ChildGridTempHelpName;
            }
            else
            {
                parentTable = ParentTableName;
                childTable = ChildTableName;
                genRef = RefGenCode;
                gridDataHelp = ChildGridHelpName;
            }
            IsValid = false;
            SetFirstFocusElement();
        }

        #endregion

        #region Delete Button

        private void ExecuteDelete(object sender, RoutedEventArgs e)
        {
            IsValid = true;

            if (CurrentRow != null)
            {
                FormMode = Modes.Delete;
                
                if (DataValidationToDelete())
                {
                    MessageBoxResult isProceed;
                    isProceed = MessageService.ShowMessage(MessageText.InquireDeletion, Title, MessageType.QuizYesNo);
                    if (isProceed == MessageBoxResult.Yes)
                    {
                        OldDataRow = CurrentRow;
                        if (DeleteRecord())
                            MessageService.ShowMessage(MessageText.DeletedSuccessfully, Title, MessageType.InfoOK);
                        else
                            MessageService.ShowMessage(MessageText.ErrorWhileSaving, Title, MessageType.InfoOK);

                        ResetDefaults();
                    }

                }
                else
                    MessageService.ShowMessage(MessageText.DeleteNotAllowed, Title, MessageType.InfoOK);

            }
            else
                MessageService.ShowMessage(MessageText.EmptyTableDeleteEditBlock, Title, MessageType.InfoOK);
        }

        #endregion

        #region Undo Button

        private void ExecuteUndo(object sender, RoutedEventArgs e)
        {
            ResetDefaults();
        }

        #endregion

        #region Navigation Buttons

        #region Move into previous record
        private void ExecutePrev(object sender, RoutedEventArgs e)
        {
            CurrentRow = ReadService.GetPreviousOrNextTransactionRecord(parentTable, (int)primaryKey, PrimaryKeyField, false);
        }
        #endregion

        #region Move into next record
        private void ExecuteNext(object sender, RoutedEventArgs e)
        {
            CurrentRow = ReadService.GetPreviousOrNextTransactionRecord(parentTable, (int)primaryKey, PrimaryKeyField, true);
        }
        #endregion

        #endregion

        #region Save Button

        private void ExecuteSave(object sender, RoutedEventArgs e)
        {
            IsValid = true;
            if (DataValidation())
            {
                NewDataRow = CurrentRow;

                if (FormMode == Modes.New)
                    InsertRecord();
                else if (FormMode == Modes.Edit)
                    UpdateRecord();

                if (IsValid)
                {
                    MessageService.ShowMessage(MessageText.SavedSuccessfully, Title, MessageType.InfoOK);
                }
                else
                    MessageService.ShowMessage(MessageText.ErrorWhileSaving, Title, MessageType.InfoOK);

                ResetDefaults();
            }
        }
                
        #endregion

        #region Close Button

        private void ExecuteClose(object sender, RoutedEventArgs e)
        {
            Window parentwin = Window.GetWindow(this);
            if (parentwin != null)
                parentwin.Close();
        }

        #endregion

        #region Print Button

        private void ExecutePrint(object sender, RoutedEventArgs e)
        {
            List<IReportParameters> repParaList = new List<IReportParameters>();
            repParaList.Add(new ReportParameters() { ParameterIndex = 0, ParameterName = "ReportName", InputValue = Title });
            repParaList.Add(new ReportParameters() { ParameterIndex = 1, ParameterName = "CompanyName", InputValue = GlobalVariables.CompanyName });
            repParaList.Add(new ReportParameters() { ParameterIndex = 2, ParameterName = "Address", InputValue = GlobalVariables.Address });
            repParaList.Add(new ReportParameters() { ParameterIndex = 3, ParameterName = "ContactDetails", InputValue = GlobalVariables.ContactDetails });
            repParaList.Add(new ReportParameters() { ParameterIndex = 4, ParameterName = "GeneratedUser", InputValue = GlobalVariables.LoggedInUser });
            repParaList.Add(new ReportParameters() { ParameterIndex = 5, ParameterName = "GenaratedMachine", InputValue = Environment.MachineName });
            repParaList.Add(new ReportParameters() { ParameterIndex = 6, ParameterName = "CopyRight", InputValue = GlobalVariables.CopyRight });
            repParaList.Add(new ReportParameters() { ParameterIndex = 7, ParameterName = "PrimaryKey", InputValue = primaryKey });
            repParaList.Add(new ReportParameters() { ParameterIndex = 8, ParameterName = "OnlineDetails", InputValue = GlobalVariables.OnlineDetails });

            if (AddAddtionalReportParameters != null)
            {
                AddAddtionalReportParameters(sender, e);          //use 9 as start ParameterIndex
                if (AdditionalReportParameters != null && AdditionalReportParameters.Count > 0)
                {
                    foreach (IReportParameters repParamItem in AdditionalReportParameters)
                        repParaList.Add(repParamItem);
                }

            }

            DataTable dtReport = new DataTable();
            dtReport.Rows.Add(CurrentRow);

            ReportsDocument ReportsDocument = new ReportsDocument();

            if (ReportsDocument != null)
            {
                ReportsDocument.InputValueList = repParaList;
                ReportDocument reportdoc;

                reportdoc = ReportsDocument.GetReportDocument(ReportFolder + ":" + ReportName.Trim(), dtReport); ;
                if (reportdoc != null)
                {
                    ReportViewerViewModel vmReportWindow = new ReportViewerViewModel(reportdoc, Title);
                    if (vmReportWindow != null)
                        MessageService.ShowReport(vmReportWindow);
                }
            }
            
        }

        #endregion

        #region Approve Button
        private void ExecuteApprove(object sender, RoutedEventArgs e)
        {

        }

        #endregion

        #region View Button
        private void ExecuteView(object sender, RoutedEventArgs e)
        {
            ResetDefaults();
            MessageBoxResult isProceed;
            if (ApproveVisibility == Visibility.Visible)
            {
                isProceed = MessageService.ShowMessage(MessageText.InquireLoadApproved, Title, MessageType.QuizYesNo);
                if (isProceed == MessageBoxResult.Yes)
                {
                    IsApproval = true;
                    parentTable = ParentTableName;
                    childTable = ChildTableName;
                    genRef = RefGenCode;
                    gridDataHelp = ChildGridHelpName;
                }
                else
                {
                    IsApproval = false;
                    parentTable = TempParentTable;
                    childTable = TempChildTable;
                    genRef = TempRefGenCode;
                    gridDataHelp = ChildGridTempHelpName;
                }
            }
            else
            {
                parentTable = ParentTableName;
                childTable = ChildTableName;
                genRef = RefGenCode;
                gridDataHelp = ChildGridHelpName;
            }
            
            FormMode = Modes.View;
            SetFirstFocusElement();
        }

        #endregion

        #region Button1 Button

        private void ExecuteButton1(object sender, RoutedEventArgs e)
        {
            
        }

        #endregion

        #region Button2 Button

        private void ExecuteButton2(object sender, RoutedEventArgs e)
        {
            
        }

        #endregion

        #region Button3 Button

        private void ExecuteButton3(object sender, RoutedEventArgs e)
        {
           
        }

        #endregion

        #region Button4 Button

        private void ExecuteButton4(object sender, RoutedEventArgs e)
        {
            
        }

        #endregion

        #region Button5 Button

        private void ExecuteButton5(object sender, RoutedEventArgs e)
        {
            
        }

        #endregion

        #region Transaction Tool Bar Loaded

        private void TransactionToolBarLoad(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;
            IsValid = false;
            ResetDefaults();
            var window = Window.GetWindow(this);
            if (window != null)
            {
                window.Title = Title;
                window.KeyDown += HandleKeyPress;           //use to manage the enter key press in parent window
            }
        }  

        #endregion

        #region Parent Window Enter Key Press Handling

        private void HandleKeyPress(object sender, KeyEventArgs e)
        {
            var parentWindow = Window.GetWindow(this);
            if (parentWindow != null)
            {
                var Uie = (UIElement)Keyboard.FocusedElement;
                if (Uie != null)
                {
                    if (e.Key == Key.Enter)
                        Uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }
            }
        }

        #endregion

        #endregion

        #region Private Methods

        private void UpdateRecord()
        {
            if (PreDataUpdate != null)
                PreDataUpdate(this, new EventArgs());

            if (IsValid && IsDataSave)
            {
                if (WriteService != null)
                {
                    var tran = SqlTran;

                    DataTable dtChilddata = DtChildTxnData.Copy();
                    DataColumnCollection correctColumns = dtDummyChild.Columns;
                    DataColumnCollection dummyColumns = DtChildTxnData.Columns;

                    foreach (DataColumn colname in dummyColumns)
                    {
                        if (!correctColumns.Contains(colname.ColumnName))
                            dtChilddata.Columns.Remove(colname.ColumnName);
                    }

                    DataRow logDataRow = DtParentLogTableData.NewRow();
                    DataColumnCollection columns = OldDataRow.Table.Columns;
                    DataColumnCollection logColumns = logDataRow.Table.Columns;

                    foreach (DataColumn logDataRowItem in logColumns)
                    {
                        if (columns.Contains(logDataRowItem.ColumnName))
                            logDataRow[logDataRowItem.ColumnName] = OldDataRow[logDataRowItem.ColumnName];
                    }

                    DataTable dtLogData = DtOldChildTxnData.Copy();
                    columns = DtChildLogTableData.Columns;
                    logColumns = DtOldChildTxnData.Columns;

                    foreach (DataColumn column in logColumns)
                    {
                        if (!columns.Contains(column.ColumnName))
                            dtLogData.Columns.Remove(column.ColumnName);
                    }

                    if (WriteService.UpdateTransactionData(parentTable, childTable, PrimaryKeyField, ReferenceNoField,
                        LogParentTable, LogChildTable, NewDataRow, logDataRow, dtLogData, dtChilddata, ref  tran, 
                        genRef, TransactionDate, BranchPrefix))
                    {
                        SqlTran = tran;
                        if (PostDataUpdate != null && IsValid)
                            PostDataUpdate(this, new EventArgs());
                    }
                    else
                    {
                        IsValid = false;
                        SqlTran = tran;
                        if (SqlTran != null)
                            SqlTran.Rollback();
                    }
                }
            }

            if (IsValid)
            {
                if (PostDataSaveProcess != null)
                {
                    PostDataSaveProcess(this, new EventArgs());
                }
                if (SqlTran != null)
                    SqlTran.Commit();
            }
            else
            {
                if (SqlTran != null && SqlTran.Connection != null)
                    SqlTran.Rollback();
            }
        }

        private void InsertRecord()
        {
            if (PreDataInsert != null)  
                PreDataInsert(this, new EventArgs());

            if (IsValid && IsDataSave)
            {
                if (WriteService != null)
                {
                    var tran = SqlTran;

                    DataTable dtChilddata = DtChildTxnData.Copy();
                    DataColumnCollection correctColumns = dtDummyChild.Columns;
                    DataColumnCollection dummyColumns = DtChildTxnData.Columns;

                    foreach (DataColumn column in dummyColumns)
                    {
                        if (!correctColumns.Contains(column.ColumnName))
                            dtChilddata.Columns.Remove(column.ColumnName);
                    }

                    if (WriteService.InsertTransactionData(parentTable, childTable, PrimaryKeyField, ReferenceNoField,
                        NewDataRow, dtChilddata, ref  tran, genRef, TransactionDate, BranchPrefix))
                    {
                        primaryKey = WriteService.PrimaryKey;
                        CurrentRow[PrimaryKeyField] = primaryKey;
                        referenceNo = WriteService.ReferenceNo;
                        CurrentRow[ReferenceNoField] = referenceNo;
                        SqlTran = tran;
                        if (PostDataInsert != null && IsValid)
                            PostDataInsert(this, new EventArgs());
                    }
                    else
                    {
                        IsValid = false;
                        SqlTran = tran;
                        if (SqlTran != null)
                            SqlTran.Rollback();
                    }
                }
            }

            if (IsValid)
            {
                if (PostDataSaveProcess != null)
                {
                    PostDataSaveProcess(this, new EventArgs());
                }
                if (SqlTran != null)
                    SqlTran.Commit();
            }
            else
            {
                if (SqlTran != null && SqlTran.Connection != null)
                    SqlTran.Rollback();
            }
        }

        //Delete Record
        private bool DeleteRecord()
        {
            if (PreDataDelete != null)
                PreDataDelete(this, new EventArgs());

            if (IsValid && IsDataDelete)
            {
                if (WriteService != null)
                {
                    var tran = SqlTran;
                    DataRow logDataRow = DtParentLogTableData.NewRow();
                    DataColumnCollection columns = OldDataRow.Table.Columns;
                    DataColumnCollection logColumns = logDataRow.Table.Columns;

                    foreach (DataColumn logDataRowItem in logColumns)
                    {
                        if (columns.Contains(logDataRowItem.ColumnName))
                            logDataRow[logDataRowItem.ColumnName] = OldDataRow[logDataRowItem.ColumnName];
                    }

                    DataTable dtLogData = DtOldChildTxnData.Copy();
                    columns = DtChildLogTableData.Columns;
                    logColumns = DtOldChildTxnData.Columns;

                    foreach (string colname in logColumns)
                    {
                        if (!columns.Contains(colname))
                            dtLogData.Columns.Remove(colname);
                    }

                    if (WriteService.DeleteTransactionData(parentTable, childTable, PrimaryKeyField, LogParentTable,
                        LogChildTable, logDataRow, dtLogData, ref tran))
                    {
                        SqlTran = tran;
                        if (PostDataDelete != null && IsValid)
                            PostDataDelete(this, new EventArgs());
                    }
                    else
                    {
                        IsValid = false;
                        SqlTran = tran;
                        if (SqlTran != null)
                            SqlTran.Rollback();
                    }
                }
            }

            if (IsValid)
            {
                if (SqlTran != null)
                    SqlTran.Commit();
            }
            else
            {
                if (SqlTran != null && SqlTran.Connection != null)
                    SqlTran.Rollback();
            }

            return IsValid;
        }
        
        private bool DataValidation()
        {
            if (PreDataValidation != null)
                PreDataValidation(this, new EventArgs());

            if (IsValid && IsDataValidateExecute)
            {
                
            }

            if (PostDataValidation != null && IsValid)
                PostDataValidation(this, new EventArgs());

            return IsValid;
        }

        //Data Validation Before Delete
        private bool DataValidationToDelete()
        {
            if (PreDataDelValidation != null)
                PreDataDelValidation(this, new EventArgs());

            if (IsValid && IsDataDelValidateExecute)
                CheckValidyofDeletion();

            if (PostDataDelValidation != null && IsValid)
                PostDataDelValidation(this, new EventArgs());

            return IsValid;
        }

        //Data Validation Before Delete
        private void CheckValidyofDeletion()
        {
            IgnoreTableList = IgnoreTableList + "," + childTable;
            int primaryKey = (int)CurrentRow[primaryKeyField];
            IsValid = CommonValidations.CheckValidyOfDeletion(parentTable, primaryKey, PrimaryKeyField, IgnoreTableList);
        }

        private void SetFirstFocusElement()
        {
            var parentWindow = Window.GetWindow(this);

            ContentControl content = (ContentControl)parentWindow.FindName("popupContent");

            DependencyObject contentPresenter = VisualTreeHelper.GetChild(content, 0);

            UserControl userControl = VisualTreeHelper.GetChild(contentPresenter, 0) as UserControl;

            var uie = (UIElement)userControl.FindName(FirstFocusElement);

            if (FormMode == Modes.Edit || FormMode == Modes.View)
                uie.Focus();
            else if (FormMode == Modes.New)
                uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        }

        private void SetOldDataVersion()
        {
            OldDataRow = DtParentTxnData.NewRow();
            foreach (DataColumn item in CurrentRow.Table.Columns)
            {
                OldDataRow[item.ColumnName] = CurrentRow[item.ColumnName];
            }
            if (DtOldChildTxnData != null)
                DtOldChildTxnData.Clear();

            if (DtChildTxnData != null)
                DtOldChildTxnData = DtChildTxnData.Copy();
        }

        private void LoadGridData()
        {
            if (PreDataGridLoad != null)
                PreDataGridLoad(this, new EventArgs());

            if (IsDataGridLoadExecute)
            {
                LoadChildTable();
            }

            //if (AddAdditionalDataColumns != null)
            //{
            //    AddAdditionalDataColumns(this, new EventArgs());
            //    if (AdditionalDataColumns != null && AdditionalDataColumns.Count > 0)
            //    {
            //        DataColumnCollection exsistsDataColumns = dtChildTxn.Columns;
            //        foreach (string dataColItem in AdditionalDataColumns)
            //            if (!exsistsDataColumns.Contains(dataColItem))
            //                dtChildTxn.Columns.Add(dataColItem);
            //    }
            //}
            DtChildTxnData = dtChildTxn.Copy();
                        
            SetOldDataVersion();
        }

        private void CheckFirstLast()
        {
            if (FormMode == Modes.View)
            {
                DataRow dr = ReadService.GetPreviousOrNextTransactionRecord(parentTable, (int)primaryKey, PrimaryKeyField, false);
                if (dr == null)
                    isFirst = true;
                else
                    isFirst = false;
                dr = ReadService.GetPreviousOrNextTransactionRecord(parentTable, (int)primaryKey, PrimaryKeyField, true);
                if (dr == null)
                    isLast = true;
                else
                    isLast = false;

                EnableDisableButtons();
            }
        }

        private void ResetDefaults()
        {
            if (PreResetDefault != null)
                PreResetDefault(this, new EventArgs());

            if (IsResetDefaultExecute)
            {
                LoadDataTables();
                LoadLogTables();
                FormMode = Modes.None;
                //SetCurrentRecord(0);
                SqlTran = null;
                IsValid = true;
            }

            if (PostResetDefault != null)
                PostResetDefault(this, new EventArgs());

            
        }

        //private void SetCurrentRecord(int rowIndex)
        //{
        //    if (DtParentTxnData != null && DtParentTxnData.Rows.Count > 0)
        //    {
        //        currentIndex = DtParentTxnData.Rows.Count <= rowIndex ? rowIndex - 1 : rowIndex;
        //        CurrentRow = DtParentTxnData.Rows[currentIndex];
        //        CurrentIndex = currentIndex;
        //    }
        //    else
        //        CurrentRow = DtParentTxnData.NewRow();

        //    EnableDisableButtons();
        //}

        private void LoadLogTables()
        {
            if (ReadService != null)
            {
                DtParentLogTableData = ReadService.GetDummyRecord(LogParentTable);
                DtChildLogTableData = ReadService.GetDummyRecord(LogChildTable);
            }
        }

        private void LoadDataTables()
        {
            if (ReadService != null)
            {
                if (ApproveVisibility == Visibility.Visible)
                {
                    DtParentTxnData = ReadService.GetDummyRecord(TempParentTable);
                    DtChildTxnData= ReadService.GetDummyRecord(TempChildTable);
                }
                else
                {
                    DtParentTxnData = ReadService.GetDummyRecord(ParentTableName);
                    DtChildTxnData = ReadService.GetDummyRecord(ChildTableName);
                }
                dtDummyChild = DtChildTxnData.Clone();
            }
        }

        //Change properties when form mode changing
        private void EnableDisableButtons(Modes formMode)
        {
            isNavigationEnable = false;
            isSaveEnable = false;
            isViewEnable = false;
            switch (formMode)
            {
                case Modes.New:
                    isSaveEnable = true;
                    break;
                case Modes.Edit:
                    isSaveEnable = true;
                    break;
                case Modes.Delete:
                    isSaveEnable = false;
                    break;
                case Modes.Approve:
                    isSaveEnable = true;
                    break;
                case Modes.Print:
                    isSaveEnable = false;
                    break;
                case Modes.Save:
                    break;
                case Modes.Undo:
                    break;
                case Modes.None:
                    isSaveEnable = false;
                    break;
                case Modes.View:
                    isViewEnable = true;
                    isNavigationEnable = true;
                    break;
                case Modes.Cancel:
                    break;
                default:
                    break;
            }
            EnableDisableButtons();
        }

        //Enable Dissable buttons due to changes of FormMode & CurrentIndex
        private void EnableDisableButtons()
        {
            btnNew.IsEnabled = (!isSaveEnable);
            btnEdit.IsEnabled = (!isSaveEnable);
            btnApprove.IsEnabled = (!isSaveEnable);
            btnDelete.IsEnabled = (isViewEnable);//(!isSaveEnable);
            btnUndo.IsEnabled = (isSaveEnable);
            btnPrevious.IsEnabled = (isNavigationEnable && !isFirst);
            btnNext.IsEnabled = (isNavigationEnable && !isLast);
            btnView.IsEnabled = (!isSaveEnable);
            btnPrint.IsEnabled = (isViewEnable);//(!isSaveEnable);
            btnSave.IsEnabled = (isSaveEnable);
            btnClose.IsEnabled = (!isSaveEnable);
        }

        private void LoadChildTable()
        {
            if (IsApproval)
                dtChildTxn = ReadService.GetChildTransactionData(ChildGridHelpName, primaryKey);
            else
                dtChildTxn = ReadService.GetChildTransactionData(ChildGridTempHelpName, primaryKey);
        }

        #endregion
    }

}